﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace BackgroundTaskLib.TestUI
{
    public class TaskManagerViewModel : BaseViewModel
    {
        private const int DefaultIntervalDelay = 1000;
        private const int DefaultRemovalDelay = 1000;

        public TaskManagerViewModel(TaskManager taskManager = null, int intervalDelay = DefaultIntervalDelay, int removalDelay = DefaultRemovalDelay)
        {
            TaskManager = taskManager ?? new TaskManager();
            IntervalDelay = intervalDelay;
            RemovalDelay = removalDelay;

            Tasks = new ObservableCollection<BackgroundTaskViewModel>();

            taskManager.Queue(new BackgroundTask(UIUpdater, "UI Updater", tag: BackgroundTask.SystemTaskTag));
        }

        public TaskManager TaskManager { get; private set; }
        public ObservableCollection<BackgroundTaskViewModel> Tasks { get; private set; }

        private int IntervalDelay { get; set; }
        private int RemovalDelay { get; set; }

        public BackgroundTask Queue(BackgroundTask task)
        {
            return TaskManager.Queue(task);
        }

        public BackgroundTask QueueAfter(BackgroundTask parent, BackgroundTask task)
        {
            return TaskManager.QueueAfter(parent, task);
        }

        private void UIUpdater(Func<double, string, bool> progressAction)
        {
            while (progressAction(-1, null) == false)
            {
                Queue(new BackgroundTask(Update, "Update UI Task", true, tag: BackgroundTask.SystemTaskTag));

                Thread.Sleep(IntervalDelay);
            }
        }

        private void Update()
        {
            var tasks = TaskManager.GetTasks(x => BackgroundTaskViewModel.CheckIsHidden(x) == false).Select((Task, i) => new { Task, i }).ToList();
            var newTasks = tasks.Where(x => Tasks.Select(y => y.Task).Contains(x.Task) == false).ToList();
            var oldTasks = Tasks.Where(x => tasks.Select(y => y.Task).Contains(x.Task) == false).ToList();

            foreach (var task in newTasks)
            {
                Tasks.Insert(task.i, new BackgroundTaskViewModel(task.Task));
            }

            foreach (var task in oldTasks)
            {
                task.OnRemoving();

                Queue(new BackgroundTask(() => Tasks.Remove(task), "Remove UI Task", true, delay: RemovalDelay, tag: BackgroundTask.SystemTaskTag));
            }

            foreach (var task in Tasks)
            {
                task.Refresh();
            }
        }
    }
}
